package org.javanum.number;

/**
 * <p>Represents a Subgroup of an abstract {@link Group}.</p>
 * 
 * <p>A <i>Subgroup</i> is a subset {@code S} of the larger Group set 
 * {@code T}, which is also a group under the defined operation 
 * {@code +}. For more information, see {@link Group}.</p>
 * 
 * <p>This interface contracts the traditional behavior of subgroups:
 * elements in a subgroup can be treated as elements in their own group,
 * OR as elements in the containing supergroup, but the implementations 
 * of the operations in the subgroup may be different than the 
 * implementations of the group itself. To this end, it enforces an
 * <i>overloading</i> of the group operations, which allowing the 
 * typical Group methods to remain unchanged.</p>
 * 
 * @author Scott Fines
 * Date: Oct 31, 2009
 *
 * @param <V> the return type of subgroup operations.
 * @param <T> the return type of the supergroup operations.
 */
public interface SubGroup<V extends SubGroup<V,T>,T extends Group<T>> 
						extends Group<T> {
	
	/**
	 * 
	 * @param value the Subgroup element to be added
	 * @return the result of the computation {@code this+value}.
	 * @see {@link #add(Group)}
	 */
	public V add(V value);
	
	/**
	 * 
	 * @param value the Subgroup element to be subtracted.
	 * @return the result of the computation {@code this-value}
	 * @see {@link #subtract(Group)}
	 */
	public V subtract(V value);
	
	/**
	 * 
	 * @return the additive Inverse of {@code this} as an implementation 
	 * of this interface
	 * @see {@link #additiveInverse()}
	 */
	public V additiveInverseAsSubElement();
	
	/**
	 * 
	 * @return the additive identity as an implementation of this interface.
	 * @see {@link #additiveIdentity()}
	 */
	public V additiveIdentityAsSubElement();

}
